import { PlusOutlined } from '@ant-design/icons';
import { message, Modal, Upload } from 'antd';
import type { ImgCropProps } from 'antd-img-crop';
import ImgCrop from 'antd-img-crop';
import React, { useEffect, useState } from 'react';
import { getSign } from './service';
import Compressor from 'compressorjs';
import type { RcFile } from 'antd/lib/upload';

type ImgUrl = string[];

interface compressorProps {
  quality?: number;
  maxWidth?: number;
  maxHeight?: number;
}

interface ImgUploadProps {
  id?: string;
  data?: ImgUrl;
  value?: ImgUrl;
  onChange?: (value: ImgUrl) => void;
  accessSecret?: string;
  accessId?: string;
  type?: number;
  callback?: (data: any) => any;
  limit?: number; // 上传最大限制
  needCrop?: boolean;
  cropProps?: ImgCropProps; // 图片裁剪参数
  resizeProps?: compressorProps; // 图片压缩参数
}

const getBase64 = (file: any) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);

    reader.onload = () => resolve(reader.result);

    reader.onerror = (error) => reject(error);
  });

const OssMulImgUpload: React.FC<ImgUploadProps> = ({
  id = '',
  value = [],
  onChange,
  accessId = '16562668728a4af697c421e3c1d88afe',
  accessSecret = 'd6a8056a8617ff313edebe41074dc5dc',
  type,
  limit = 8,
  needCrop = false,
  cropProps,
  resizeProps = {
    // 图片压缩参数
    quality: 0.6, // 压缩力度 0 ～ 1
    maxWidth: 750, // 最大宽度
  },
  callback,
}) => {
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewImage, setPreviewImage] = useState('');
  const [previewTitle, setPreviewTitle] = useState('');
  const [fileList, setFileList] = useState<string[]>(value);
  const [formData, setFormData] = useState<any>({});

  const [OSSData, setOSSData] = useState<{
    accessId: string;
    callback: string;
    dir: string;
    expire: 1661844820;
    fileName: string;
    host: string;
    policy: string;
    signature: string;
    key: string;
  }>(); // Mock get OSS api

  const init = async () => {
    try {
      const response = await getSign({
        accessId: accessId,
        accessSecret: accessSecret,
        type: type || 1,
      });
      response.key = response.dir + response.fileName;
      setOSSData(response);
    } catch (error) {
      message.error(error);
    }
  };

  useEffect(() => {
    init();
  }, []);

  const handleCancel = () => setPreviewOpen(false);

  const handlePreview = async (file: any) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj);
    }

    setPreviewImage(file.url || file.preview);
    setPreviewOpen(true);
    setPreviewTitle(file.name || file.url.substring(file.url.lastIndexOf('/') + 1));
  };

  const handleChange = ({ fileList: newFileList }) => {
    onChange?.([...newFileList]);
    setFileList([...newFileList]);
  };

  const getExtraData = async (file: any) => {
    const response = await getSign({
      accessId: accessId,
      accessSecret: accessSecret,
      type: type || 1,
    });
    response.key = response.dir + response.fileName;
    return {
      policy: response?.policy,
      ossaccessKeyId: response?.accessId,
      key:
        response?.key +
        file.name.replace(/\s*/g, '').split('.')[0] +
        '.' +
        file.name.split('.')[file.name.split('.').length - 1],
      dir: response?.dir,
      host: response?.host,
      signature: response?.signature,
    };
  };

  const beforeUpload = async (file: RcFile) => {
    return new Promise<any>(async (resolve, reject) => {
      if (!OSSData) {
        reject();
        return;
      }
      // const expire = Number(OSSData.expire) * 1000;
      // if (expire < Date.now()) {
      // await init(); // 获取oss签名数据
      // }

      const res = await new Compressor(file, { ...resizeProps });
      const files = res?.file;
      const imgOssData = await getExtraData(files);
      // console.log('imgOssData----', imgOssData);
      files.url = OSSData.host + '/' + imgOssData.key;
      console.log('files.url----', files.url);
      setFormData(imgOssData);
      resolve(files);
      return files;
    });
  };

  const uploadButton = (
    <div>
      <PlusOutlined />
      <div
        style={{
          marginTop: 8,
        }}
      >
        上传
      </div>
    </div>
  );

  return (
    <>
      {!needCrop ? (
        <>
          <Upload
            id={id}
            action={OSSData?.host}
            listType="picture-card"
            fileList={fileList}
            data={formData}
            beforeUpload={beforeUpload}
            onPreview={handlePreview}
            onChange={handleChange}
          >
            {fileList?.length >= limit ? null : uploadButton}
          </Upload>
          <Modal visible={previewOpen} title={previewTitle} footer={null} onCancel={handleCancel}>
            <img
              alt="example"
              style={{
                width: '100%',
              }}
              src={previewImage}
            />
          </Modal>
        </>
      ) : (
        <>
          <ImgCrop {...cropProps}>
            <Upload
              id={id}
              action={OSSData?.host}
              listType="picture-card"
              fileList={fileList}
              data={formData}
              beforeUpload={beforeUpload}
              onPreview={handlePreview}
              onChange={handleChange}
            >
              {fileList?.length >= limit ? null : uploadButton}
            </Upload>
          </ImgCrop>
          <Modal visible={previewOpen} title={previewTitle} footer={null} onCancel={handleCancel}>
            <img
              alt="example"
              style={{
                width: '100%',
              }}
              src={previewImage}
            />
          </Modal>
        </>
      )}
    </>
  );
};

export default OssMulImgUpload;
